---
title: Menu
package: "@chakra-ui/menu"
image: "components/menu.svg"
description:
  An accessible dropdown menu for the common dropdown menu button design
  pattern. Menu uses roving tabIndex for focus management.
---

An accessible dropdown menu for the common dropdown menu button design pattern.
`Menu` uses roving `tabIndex` for focus management.

<ComponentLinks
  theme={{ componentName: "menu" }}
  github={{ package: "menu" }}
  npm={{ package: "@chakra-ui/menu" }}
/>

<carbon-ad></carbon-ad>

## Import

Chakra UI exports 8 components for rendering menus:

- `Menu`: The wrapper component provides context, state, and focus management.
- `MenuList`: The wrapper for the menu items. Must be a direct child of `Menu`.
- `MenuButton`: The trigger for the menu list. Must be a direct child of `Menu`.
- `MenuItem`: The trigger that handles menu selection. Must be a direct child of
  a `MenuList`.
- `MenuGroup`: A wrapper to group related menu items.
- `MenuDivider`: A visual separator for menu items and groups.
- `MenuOptionGroup`: A wrapper for checkable menu items (radio and checkbox).
- `MenuItemOption`: The checkable menu item, to be used with `MenuOptionGroup`.

```js
import {
  Menu,
  MenuButton,
  MenuList,
  MenuItem,
  MenuItemOption,
  MenuGroup,
  MenuOptionGroup,
  MenuIcon,
  MenuCommand,
  MenuDivider,
} from "@chakra-ui/react"
```

## Usage

```jsx
<Menu>
  <MenuButton as={Button} rightIcon={<ChevronDownIcon />}>
    Actions
  </MenuButton>
  <MenuList>
    <MenuItem>Download</MenuItem>
    <MenuItem>Create a Copy</MenuItem>
    <MenuItem>Mark as Draft</MenuItem>
    <MenuItem>Delete</MenuItem>
    <MenuItem>Attend a Workshop</MenuItem>
  </MenuList>
</Menu>
```

### Accessing the internal state

To access the internal state of the `Menu`, use a function as `children`
(commonly known as a render prop). You'll get access to the internal state
`isOpen` and method `onClose`.

```jsx
<Menu>
  {({ isOpen }) => (
    <>
      <MenuButton isActive={isOpen} as={Button} rightIcon={<ChevronDownIcon />}>
        {isOpen ? "Close" : "Open"}
      </MenuButton>
      <MenuList>
        <MenuItem>Download</MenuItem>
        <MenuItem onClick={() => alert("Kagebunshin")}>Create a Copy</MenuItem>
      </MenuList>
    </>
  )}
</Menu>
```

### Customizing the button

The default `MenuButton` can be styled using the usual styled-system props, but
it starts off plainly styled.

Using the `as` prop of the `MenuButton`, you can render a custom component
instead of the default `MenuButton`. For instance, you can use Chakra's `Button`
component, or your own custom component.

> Custom components must take a `ref` prop which is assigned to the React
> component that triggers the menu opening. This is so that the `MenuList`
> popover can be positioned correctly. Without this, the `MenuList` will render
> in an undefined position.

### Letter Navigation

When focus is on the `MenuButton` or within the `MenuList` and you type a letter
key, a search begins. Focus will move to the first `MenuItem` that starts with
the letter you typed.

> Open the menu, try and type any letter, (say "S") to see the focus movement.

```jsx
<Menu>
  <MenuButton
    px={4}
    py={2}
    transition="all 0.2s"
    borderRadius="md"
    borderWidth="1px"
    _hover={{ bg: "gray.400" }}
    _expanded={{ bg: "blue.400" }}
    _focus={{ boxShadow: "outline" }}
  >
    File <ChevronDownIcon />
  </MenuButton>
  <MenuList>
    <MenuItem>New File</MenuItem>
    <MenuItem>New Window</MenuItem>
    <MenuDivider />
    <MenuItem>Open...</MenuItem>
    <MenuItem>Save File</MenuItem>
  </MenuList>
</Menu>
```

### Just another example

```jsx
<Menu>
  <MenuButton as={Button} rightIcon={<ChevronDownIcon />}>
    Your Cats
  </MenuButton>
  <MenuList>
    <MenuItem minH="48px">
      <Image
        boxSize="2rem"
        borderRadius="full"
        src="https://placekitten.com/100/100"
        alt="Fluffybuns the destroyer"
        mr="12px"
      />
      <span>Fluffybuns the Destroyer</span>
    </MenuItem>
    <MenuItem minH="40px">
      <Image
        boxSize="2rem"
        borderRadius="full"
        src="https://placekitten.com/120/120"
        alt="Simon the pensive"
        mr="12px"
      />
      <span>Simon the pensive</span>
    </MenuItem>
  </MenuList>
</Menu>
```

### Adding icons and commands

You can add icon to each `MenuItem` by passing the `icon` prop. To add a
commands (or hotkeys) to menu items, you can use the `command` prop.

```jsx
<Menu>
  <MenuButton
    as={IconButton}
    aria-label="Options"
    icon={<HamburgerIcon />}
    variant="outline"
  />
  <MenuList>
    <MenuItem icon={<AddIcon />} command="⌘T">
      New Tab
    </MenuItem>
    <MenuItem icon={<ExternalLinkIcon />} command="⌘N">
      New Window
    </MenuItem>
    <MenuItem icon={<RepeatIcon />} command="⌘⇧N">
      Open Closed Tab
    </MenuItem>
    <MenuItem icon={<EditIcon />} command="⌘O">
      Open File...
    </MenuItem>
  </MenuList>
</Menu>
```

### Lazily mounting MenuItem

By default, the `Menu` component renders all children of `MenuList` to the DOM,
meaning that invisible menu items are still rendered but are hidden by styles.

If you want to defer rendering of each children of `MenuList` until that menu is
open, you can use the `isLazy` prop. This is useful if your `Menu` needs to be
extra performant, or make network calls on mount that should only happen when
the component is displayed.

```jsx
<Menu isLazy>
  <MenuButton>Open menu</MenuButton>
  <MenuList>
    {/* MenuItems are not rendered unless Menu is open */}
    <MenuItem>New Window</MenuItem>
    <MenuItem>Open Closed Tab</MenuItem>
    <MenuItem>Open File</MenuItem>
  </MenuList>
</Menu>
```

### Rendering menu in a portal

To render menus in a portal, import the `Portal` component and wrap the
`MenuList` within the `Portal`.

```jsx
<Menu>
  <MenuButton>Open menu</MenuButton>
  <Portal>
    <MenuList>
      <MenuItem>Menu 1</MenuItem>
      <MenuItem>New Window</MenuItem>
      <MenuItem>Open Closed Tab</MenuItem>
      <MenuItem>Open File</MenuItem>
    </MenuList>
  </Portal>
</Menu>
```

### MenuGroup

To group related `MenuItem`s, use the `MenuGroup` component and pass it a
`title` for the group name.

```jsx
<Menu>
  <MenuButton as={Button} colorScheme="pink">
    Profile
  </MenuButton>
  <MenuList>
    <MenuGroup title="Profile">
      <MenuItem>My Account</MenuItem>
      <MenuItem>Payments </MenuItem>
    </MenuGroup>
    <MenuDivider />
    <MenuGroup title="Help">
      <MenuItem>Docs</MenuItem>
      <MenuItem>FAQ</MenuItem>
    </MenuGroup>
  </MenuList>
</Menu>
```

## Menu option groups

You can compose a menu for table headers to help with sorting and filtering
options. Use the `MenuOptionGroup` and `MenuItemOption` components.

```jsx
<Menu closeOnSelect={false}>
  <MenuButton as={Button} colorScheme="blue">
    MenuItem
  </MenuButton>
  <MenuList minWidth="240px">
    <MenuOptionGroup defaultValue="asc" title="Order" type="radio">
      <MenuItemOption value="asc">Ascending</MenuItemOption>
      <MenuItemOption value="desc">Descending</MenuItemOption>
    </MenuOptionGroup>
    <MenuDivider />
    <MenuOptionGroup title="Country" type="checkbox">
      <MenuItemOption value="email">Email</MenuItemOption>
      <MenuItemOption value="phone">Phone</MenuItemOption>
      <MenuItemOption value="country">Country</MenuItemOption>
    </MenuOptionGroup>
  </MenuList>
</Menu>
```

## Accessibility

### Keyboard Interaction

| Key                | Action                                                                                                                                  |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| `Enter` or `Space` | When `MenuButton` receives focus, opens the menu and places focus on the first menu item.                                               |
| `ArrowDown`        | When `MenuButton` receives focus, opens the menu and moves focus to the first menu item.                                                |
| `ArrowUp`          | When `MenuButton` receives focus, opens the menu and moves focus to the last menu item.                                                 |
| `Escape`           | When the menu is open, closes the menu and sets focus to the `MenuButton`.                                                              |
| `Tab`              | no effect                                                                                                                               |
| `Home`             | When the menu is open, moves focus to the first item.                                                                                   |
| `End`              | When the menu is open, moves focus to the last item.                                                                                    |
| `A-Z` or `a-z`     | When the menu is open, moves focus to the next menu item with a label that starts with the typed character if such an menu item exists. |

### ARIA roles

**For `MenuButton`:**

- `role` is set to `button`.
- `aria-haspopup` is set to `menu`.
- When the menu is displayed, `aria-expanded` is set to `true`.
- `aria-controls` is set to the `id` of the `MenuList`.

**For `MenuList`:**

- `role` is set to `menu`.
- `aria-orientation` is set to `vertical`.

**For `MenuItem`:**

- `role` is set to `menuitem`.
- Gets one of these roles `menuitem`/`menuitemradio`/ `menuitemcheckbox`.

## Props

### Menu Props

<PropsTable of="Menu" />

### MenuButton Props

`MenuButton` composes [Box](/docs/layout/box) so you can pass all `Box` props to
change its style.

### MenuList Props

`MenuList` composes [Box](/docs/layout/box) so you can pass all `Box` props to
change its style.

### MenuItem Props

<PropsTable of="MenuItem" />

### MenuGroup Props

`MenuGroup` composes [Box](/docs/layout/box) so you can pass all `Box` props to
change its style.

### MenuOptionGroup Props

<PropsTable of="MenuOptionGroup" />

### MenuItemOption Props

`MenuItemOption` composes [Box](/docs/layout/box) so you can pass all box props
in addition to these:

<PropsTable of="MenuItemOption" />
